package iputil

import (
	"fmt"
	"io"
	"net"
	"net/http"
	"regexp"
	"strings"
	"sync"
	"time"
)

// 默认IPv4检测服务
var defaultIPv4Services = []string{
	"https://api.ipify.org",
	"https://ifconfig.me/ip",
	"https://icanhazip.com",
	"https://ipinfo.io/ip",
}

// 默认IPv6检测服务
var defaultIPv6Services = []string{
	"https://api6.ipify.org",
	"https://ifconfig.co/ip",
	"https://ipv6.icanhazip.com",
	"https://v6.ident.me",
	"http://v6.66666.host:66/ip", // 用户推荐的服务
	"https://ipv6.lookup.test-ipv6.com/ip/",
	"https://ipv6.whatismyip.com",
	"https://bot.whatismyipaddress.com",
}

// 实际使用的服务列表，可以通过SetServices更新
var (
	ipv4Services = defaultIPv4Services
	ipv6Services = defaultIPv6Services
	serviceMutex sync.RWMutex
)

// SetIPv4Services 设置IPv4检测服务列表
func SetIPv4Services(services []string) {
	serviceMutex.Lock()
	defer serviceMutex.Unlock()
	
	if len(services) > 0 {
		ipv4Services = services
	} else {
		ipv4Services = defaultIPv4Services
	}
}

// SetIPv6Services 设置IPv6检测服务列表
func SetIPv6Services(services []string) {
	serviceMutex.Lock()
	defer serviceMutex.Unlock()
	
	if len(services) > 0 {
		ipv6Services = services
	} else {
		ipv6Services = defaultIPv6Services
	}
}

// GetIPv4Services 获取当前IPv4检测服务列表
func GetIPv4Services() []string {
	serviceMutex.RLock()
	defer serviceMutex.RUnlock()
	
	// 返回副本，避免外部修改
	services := make([]string, len(ipv4Services))
	copy(services, ipv4Services)
	return services
}

// GetIPv6Services 获取当前IPv6检测服务列表
func GetIPv6Services() []string {
	serviceMutex.RLock()
	defer serviceMutex.RUnlock()
	
	// 返回副本，避免外部修改
	services := make([]string, len(ipv6Services))
	copy(services, ipv6Services)
	return services
}

// 验证IP地址是否符合指定的版本
func isValidIP(ip string, wantIPv6 bool) bool {
	parsedIP := net.ParseIP(ip)
	if parsedIP == nil {
		return false // 不是有效的IP地址
	}
	
	// 检查是否是IPv6地址
	isIPv6 := parsedIP.To4() == nil
	
	return isIPv6 == wantIPv6
}

// 从响应中提取IP地址
// 有些服务返回的不仅仅是IP地址，可能包含其他文本
func extractIP(content string) string {
	// 使用正则表达式匹配IPv4或IPv6地址
	ipv4Regex := regexp.MustCompile(`\b(?:\d{1,3}\.){3}\d{1,3}\b`)
	ipv6Regex := regexp.MustCompile(`([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)`)
	
	// 优先尝试匹配IPv6地址
	if ipv6Match := ipv6Regex.FindString(content); ipv6Match != "" {
		return ipv6Match
	}
	
	// 然后尝试匹配IPv4地址
	if ipv4Match := ipv4Regex.FindString(content); ipv4Match != "" {
		return ipv4Match
	}
	
	// 如果没有匹配到，返回原始内容（可能是纯IP地址）
	return content
}

// GetPublicIP 通过多个服务获取当前公共IP地址，提供冗余能力
// ipVersion 可以是 "ipv4" 或 "ipv6"
func GetPublicIP(ipVersion string) (string, error) {
	serviceMutex.RLock()
	var services []string
	if ipVersion == "ipv6" {
		services = make([]string, len(ipv6Services))
		copy(services, ipv6Services)
	} else {
		services = make([]string, len(ipv4Services))
		copy(services, ipv4Services)
	}
	serviceMutex.RUnlock()
	
	wantIPv6 := ipVersion == "ipv6"
	
	var lastErr error
	client := &http.Client{
		Timeout: 10 * time.Second,
	}

	for _, service := range services {
		resp, err := client.Get(service)
		if err != nil {
			lastErr = err
			continue
		}
		defer resp.Body.Close()

		ip, err := io.ReadAll(resp.Body)
		if err != nil {
			lastErr = err
			continue
		}

		// 清理并提取IP地址
		ipStr := strings.TrimSpace(string(ip))
		ipStr = extractIP(ipStr)
		
		// 验证IP地址是否有效且符合请求的类型
		if ipStr != "" && isValidIP(ipStr, wantIPv6) {
			return ipStr, nil
		}
	}

	if wantIPv6 {
		return "", fmt.Errorf("无法获取有效的IPv6地址，您的网络可能不支持IPv6或IPv6服务不可用: %v", lastErr)
	}
	return "", fmt.Errorf("无法获取有效的IPv4地址: %v", lastErr)
} 